/*
    Static JS for Tree Map
*/

// Global vars
var analysisTreeMap = null;
var labelType, useGradients, nativeTextSupport, animate;

var tmData = {};
var tmCurrentLevel = 0;
var tmMaxLevel = 3; // maximum depth we can explore
var tmCurrentNode = null;

var tmHColors = ['#999', '#ff5121', '#f4961c', '#d6b317', '#77b82e', '#059346'];
var tmLColors = ['#141414', '#36150C', '#33210B', '#2E270A', '#212E14', '#19260C'];
var tmLevels = null;

(function() {
  var ua = navigator.userAgent,
      iStuff = ua.match(/iPhone/i) || ua.match(/iPad/i),
      typeOfCanvas = typeof HTMLCanvasElement,
      nativeCanvasSupport = (typeOfCanvas == 'object' || typeOfCanvas == 'function'),
      textSupport = nativeCanvasSupport && (typeof document.createElement('canvas').getContext('2d').fillText == 'function');
  //I'm setting this based on the fact that ExCanvas provides text support for IE
  //and that as of today iPhone/iPad current text support is lame
  labelType = (!nativeCanvasSupport || (textSupport && !iStuff))? 'Native' : 'HTML';
  nativeTextSupport = labelType == 'Native';
  useGradients = nativeCanvasSupport;
  animate = !(iStuff || !nativeCanvasSupport);
})();

var Log = {
  elem: false,
  write: function(text){
    if (!this.elem) {
      this.elem = document.getElementById('log');
    }
    this.elem.innerHTML = text;
    this.elem.style.left = (500 - this.elem.offsetWidth / 2) + 'px';
  }
};

function tmAddLocation(id, location) {
    // Add a location to tmData
    var item = tmData[id];
    if (typeof item == 'undefined') {
        tmData[id] = location;
    } else {
        // Item exists - only update x
        if (!location.x) {
            item.x = false;
        }
    }
}

function tmLevelName(level) {
    if (level === 0) {
        return (i18n.country);
    } else {
        lname = 'l' + level;
        if (tmLevels.hasOwnProperty(lname)) {
            return tmLevels[lname];
        }
    }
    return '';
}

function tmUpdateHierarchy() {
    // Update the location hierarchy
    for (var i in tmData) {
        tmData[i].c = [];
    }
    for (var j in tmData) {
        var item = tmData[j];
        var parent_id = item.f;
        if (parent_id !== null) {
            try {
                var parent = tmData[parent_id];
                parent.c.push(j);
            }
            catch(e) {
                continue;
            }
        }
    }
}

function tmBuildGraph(id, indicator) {
    // Build the tree graph
    tmLevels = hdata[$('#l0_analysis1s').val()];

    var item = tmData[id];
    if (item.f !== null) {
        return tmBuildGraph(item.f, indicator);
    } else {
        return tmAddNode(id, indicator);
    }
}

function tmPopulation(item) {
    // Get the population for a node
    var population = item.p;
    if (population !== 0) {
        var tot = item.t;
        var cnt = item.r;
        if (tot && cnt && tot != cnt) {
            // Extrapolate
            population += population / (tot - cnt) * cnt;
        }
    }
    return population;
}

function tmAddNode(id, indicator) {
    // Add a node to the tree graph

    // Get the item
    var item = tmData[id];
    if (typeof item == 'undefined') {
        return null;
    }

    // Add all children
    var children = [];
    for (var i=0; i < item.c.length; i++) {
        child = tmAddNode(item.c[i], indicator);
        if (child !== null) {
            children.push(child);
        }
    }

    // Color
    var value = item.i[indicator];
    var color_index = 0;
    if (typeof value != 'undefined') {
        color_index = value.toFixed(0);
        if (color_index < 1 || color_index > 5) {
            color_index = 0;
        }
    }
    var color = tmLColors[color_index];

    // Area
    var area = 100;
    var population = tmPopulation(item);
    if (population !== 0) {
        area = population;
    } else {
        area = Math.pow(10, 6 - item.l);
    }

    // Create the node
    var node = {
        id: id,
        name: item.n,
        data: {
            level: item.l,
            population: item.p,
            indicator: indicator,
            color_index: color_index,
            value: value,
            '$color': color,
            '$area': area.toFixed(0)
        },
        children: children
    };
    return node;
}

function tmUpdate() {
    // Update the tree graph for the current indicator
    var indicator = $('.indicatorRatingLabel input[type=radio]:checked').val();
    var graph = analysisTreeMap.graph;
    graph.eachNode(function(node) {
        var item = tmData[node.id];
        if (item) {
            var value = item.i[indicator];
            var color_index = 0;
            if (typeof value != 'undefined' && value) {
                color_index = value.toFixed(0);
                if (color_index < 1 || color_index > 5) {
                    color_index = 0;
                }
            }
            node.data['value'] = value;
            node.data['indicator'] = indicator;
            node.data['color_index'] = color_index;
            node.data['$color'] = tmLColors[color_index];
        }
    });
    tmRenderHeaders(tmCurrentNode);
    analysisTreeMap.plot();
}

function tmGoToLocation(id) {
    // Update the tree map for the location specified by id
    // and the indicator specified by indicator

    var indicator = $('.indicatorRatingLabel input[type=radio]:checked').val();
    $('.indicatorRatingLabel input[type=radio]').change(function() {
        tmUpdate();
    });
    if (analysisTreeMap === null) {
        tmInit();
    }
    var location = tmData[id];
    if (typeof location == 'undefined' || location['x']) {
        $.ajax({
            'url': S3.Ap.concat('/vulnerability/tmdata/') + id,
            'success': function(data) {
                for (var l in sdata) {
                    tmAddLocation(l, sdata[l]);
                }
                tmUpdateHierarchy();
                var json = tmBuildGraph(id, indicator);
                analysisTreeMap.loadJSON(json);
                tmRenderHeaders(id);
                var node = analysisTreeMap.graph.getNode(id);
                if (node) {
                    analysisTreeMap.enter(node);
                }
                if (node.data.level < tmMaxLevel - 1) {
                    $('#treeMapChart .node').css({cursor: 'pointer'});
                } else {
                    $('#treeMapChart .node').css({cursor: 'default'});
                }
            },
            'error': function(request, status, error) {
                if (error == 'UNAUTHORIZED') {
                    msg = i18n.gis_requires_login;
                } else {
                    msg = request.responseText;
                }
                console.log(msg);
            },
            'dataType': 'script'
        });
    } else {
        var json = tmBuildGraph(id, indicator);
        analysisTreeMap.loadJSON(json);
        tmRenderHeaders(id);
        var node = analysisTreeMap.graph.getNode(id);
        if (node) {
            analysisTreeMap.enter(node);
            if (node.data.level < tmMaxLevel - 1) {
                $('#treeMapChart .node').css({cursor: 'pointer'});
            } else {
                $('#treeMapChart .node').css({cursor: 'default'});
            }
        }
    }
}

function tmRenderHeaders(id) {
    // Render the headers
    $('.treeMapHeader').unbind('click');
    var item = tmData[id];

    // Set current node and level
    tmCurrentNode = id;
    tmCurrentLevel = item.l;

    var next = id;
    var headers = [];
    while(item) {
        var node = analysisTreeMap.graph.getNode(next);
        level = tmLevelName(node.data.level);
        var color_index = node.data.color_index;
        header = '<div id="treeMapGoTo_' + next + '" class="treeMapHeader treeMapHBGColor' + color_index + '">' +
                 '<div>' +
                   '<span class="treeMapValue treeMapHFGColor' + color_index + '">' + color_index + '</span>' +
                   '<span class="treeMapLocation">' + item.n + '</span>' +
                   '<span class="treeMapLevel">' + level + '</span>' +
                 '</div>' +
                 '</div>';
        headers.push(header);
        if (item.f) {
            next = item.f;
            item = tmData[item.f];
        } else {
            break;
        }
    }
    headers.reverse();
    $('#treeMapHeaders').html(headers.join(''));
    // Set background colors for headers
    for (var i=0; i <= 5; i++) {
        $('.treeMapHBGColor' + i).css({'background-color': tmHColors[i]});
        $('.treeMapHFGColor' + i).css({'color': tmHColors[i]});
    }
    // Click-event handler
    $('.treeMapHeader').click(function() {
        var id = this.id;
        var location = id.substring(id.indexOf('_') + 1);
        var node = analysisTreeMap.graph.getNode(location);
        tmGoToLocation(location);
        return false;
    });
    return;
}

function tmInit() {
    // Initialize the tree map
    if (analysisTreeMap !== null) {
        // Already initialized
        return;
    }
    analysisTreeMap = new $jit.TM.Squarified({
        injectInto: 'treeMapChart',
        titleHeight: 0,
        animate: false,
        offset: 1,
        levelsToShow: 1,
        Events: {
            enable: true,
            onClick: function(node) {
                // Step down into this node
                if (node && tmData[node.id].l < tmMaxLevel) {
                    tmGoToLocation(node.id);
                }
            },
            onRightClick: function() {
                // Go to the parent node
                var parent = tmData[tmCurrentNode].f;
                if (parent) {
                    var graph = analysisTreeMap.graph;
                    var node = graph.getNode(parent);
                    if (node) {
                        tmGoToLocation(node.id);
                    }
                }
            }
        },
        Tips: {
            enable: true,
            offsetX: 20,
            offsetY: 20,
            onShow: function(tip, node, isLeaf, domElement) {
                var data = node.data;
                var color_index = data.color_index;
                level = tmLevelName(data.level);

                // Tip title
                var html = '<div class="tipTitle">' +
                           '<div class="tipIndicator">' + color_index + '</div>' +
                           '<h5 class="tipLocation">' + node.name + '</h5>' +
                           '<h5 class="tipLevel">' + level + '</h5>' +
                           '</div>';

                // Tip text
                html += '<div class="tip-text">' +
                        '<div class="tipPopulation">' +
                        i18n.population.toUpperCase() + ': ';
                if (data.population) {
                    html += data.population;
                    // Comment/remove this section if not required:
                    if (data.population != data['$area']) {
                        html += ' (' + i18n.extrapolated.toUpperCase() + ': ' + data['$area'] + ')';
                    }
                } else {
                    html += i18n.no_data.toUpperCase();
                }
                html += '</div></div>';

                tip.innerHTML = html;
                $('.tipIndicator').css({'background-color': tmHColors[color_index]});
            }
        },
        onCreateLabel: function(domElement, node) {
            var data = node.data;
            l = data.level;
            level = tmLevelName(l);
            if (l == tmCurrentLevel + 1) {
                domElement.innerHTML = '<div class="treeMapLabel">' +
                                       '<div class="treeMapLabelName">' + node.name + '</div>' +
                                       '<div class="treeMapLabelLevel">' + level + '</div>' +
                                       '</div>';
            }
            domElement.onmouseover = function() {
                node.data['$color'] = tmHColors[node.data.color_index];
                analysisTreeMap.fx.plotNode(node, analysisTreeMap.canvas);
            };
            domElement.onmouseout = function() {
                node.data['$color'] = tmLColors[node.data.color_index];
                analysisTreeMap.fx.plotNode(node, analysisTreeMap.canvas);
            };
        }
    });
}

// End
